package com.yanqu.road.server.gameplayer.module.manor;

import com.yanqu.road.entity.config.manor.ManorConfig;
import com.yanqu.road.entity.config.npc.ManorNpcTalkInfo;
import com.yanqu.road.entity.config.skill.SkillInfo;
import com.yanqu.road.entity.config.skin.SkinInfo;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.log.LogManorProsperousValueGet;
import com.yanqu.road.entity.manor.*;
import com.yanqu.road.entity.player.PatronsFishBindingData;
import com.yanqu.road.entity.servercenter.ServerInfo;
import com.yanqu.road.logic.bussiness.player.UserFishPondBusiness;
import com.yanqu.road.logic.bussiness.player.UserManorBusiness;
import com.yanqu.road.logic.config.ChannelConfig;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.pb.manor.ManorProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.gameplayer.module.skin.SkinModule;
import com.yanqu.road.server.manger.ConfigMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.config.SkillMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.manger.manor.FishPondMgr;
import com.yanqu.road.server.manger.manor.ManorMgr;
import com.yanqu.road.server.manger.rank.RankMgr;
import com.yanqu.road.server.pb.ManorPb;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author ：zfr
 * @date ：2021/5/10 17:43
 */
public class ManorModule extends GeneralModule {
    private UserManorData userManorData;
    private ManorHarvestModel harvestModel;
    private ManorGuestModel guestModel;
    private ManorBuildingModel buildingModel;
    private ManorTechnologyModel technologyModel;
    private ManorFishPondModel fishPondModel;
    private LinkedList<ManorHelpRecord> manorHelpRecordList = new LinkedList<>();
    private static Logger logger = LogManager.getLogger(ManorModule.class.getName());
    private List<Long> currHelpUserIdList = new ArrayList<>();

    public ManorModule(GamePlayer player) {
        super(player);
    }

    public UserManorData getUserManorData() {
        return userManorData;
    }

    public ManorHarvestModel getHarvestModel() {
        return harvestModel;
    }

    public ManorGuestModel getGuestModel() {
        return guestModel;
    }

    public ManorBuildingModel getBuildingModel() {
        return buildingModel;
    }

    public ManorTechnologyModel getTechnologyModel() {
        return technologyModel;
    }

    public ManorFishPondModel getManorFishPondModel() {
        return fishPondModel;
    }

    @Override
    public boolean loadData() {
        currHelpUserIdList = new ArrayList<>();
        long userId = getUserId();
        //鱼塘模块 要先初始化数据 (避免系统没解锁前领取了鱼类鱼食 运营投放)
        FishPondData fishPondData = UserFishPondBusiness.getFishPondData(userId);
        Map<Integer, FishData> fishDataMap = UserFishPondBusiness.getFishDataMap(userId);
        Map<Integer, FishPondSpecialItemData> fishPondSpecialItemDataMap = UserFishPondBusiness.getFishPondSpecialItemDataMap(userId);
        List<FishPondTaskData> fishPondTaskDataList = UserFishPondBusiness.getFishPondTaskDataList(userId);
        Map<Integer, PatronsFishBindingData> patronsVehicleBindingDataMap = UserFishPondBusiness.getPatronsFishBindingData(player.getUserId());
        fishPondModel = new ManorFishPondModel(fishPondData, fishDataMap, fishPondSpecialItemDataMap, fishPondTaskDataList, patronsVehicleBindingDataMap, player);
        userManorData = UserManorBusiness.getUserManorData(userId);
        if (userManorData == null) {
            initUserManorData();
            return true;
        }
        //产出模块
        Map<Integer, ManorHarvestData> harvestDataMap = UserManorBusiness.getHarvestDataMap(userId);
        harvestModel = new ManorHarvestModel(harvestDataMap, player);
        //加成模块
        Map<Integer, ManorGuestData> guestDataMap = UserManorBusiness.getGuestDataMap(userId);
        guestModel = new ManorGuestModel(guestDataMap, player);
        Map<Integer, ManorBuildingData> buildingDataMap = UserManorBusiness.getBuildingDataMap(userId);
        buildingModel = new ManorBuildingModel(buildingDataMap, player);
        //科技模块
        Map<Integer, ManorTechnologyData> technologyDataMap = UserManorBusiness.getTechnologyDataMap(userId);
        technologyModel = new ManorTechnologyModel(technologyDataMap, player);
        manorHelpRecordList = UserManorBusiness.getManorHelpRecordList(player.getUserId(), GameConfig.MANOR_HEART_RECORD_MAX_COUNT);
        return true;
    }

    @Override
    public void loginSendMsg() {
        //初始化暴富鸭皮肤
        linleeSkinCheck(false);
        syncManorData();
    }

    /**
     * 解锁
     * @param id
     * @param type
     * @return
     */
    public int unLock(int id, int type) {
        if (type == eManorBigType.OutPut.getValue()) {
            return harvestModel.unLock(id);
        } else if (type == eManorBigType.Guest.getValue()) {
            return guestModel.unLock(id);
        } else if (type == eManorBigType.Building.getValue()) {
            return buildingModel.unLock(id, false);
        }
        return GameErrorCode.E_MANOR_TYPE_ERROR;
    }

    public int unLockTechnology(int id, int skillPos) {
        return technologyModel.unLock(id, skillPos);
    }

    public void technologyLevelUp(int id, int skillPos, int lvCount, ManorProto.ManorTechnologyLevelUpRespMsg.Builder respMsg) {
        technologyModel.technologyLevelUp(id, skillPos, lvCount, respMsg);
    }

    /**
     * 升级
     *
     * @param id
     * @param levelUpCount
     * @param together
     * @return
     */
    public int levelUp(int id, int levelUpCount) {
        return harvestModel.levelUp(id, levelUpCount);
    }

    public int levelUpTogether(int id, int levelUpCount) {
        return harvestModel.levelUpTogether(id, levelUpCount);
    }

    /**
     * 更换皮肤
     * @param id
     * @param type
     * @return
     */
    public int changeSkin(int id, int skinId, int type) {
        if (type == eManorBigType.OutPut.getValue()) {
            return harvestModel.changeSkin(id, skinId);
        } else if (type == eManorBigType.Building.getValue()) {
            return buildingModel.changeSkin(id, skinId);
        } else if (type == eManorBigType.Guest.getValue()) {
            return guestModel.changeSkin(id, skinId);
        }
        return GameErrorCode.E_MANOR_TYPE_ERROR;
    }

    public void autoUseSkin(int belong, int skinId) {
        if (belong <= 200) {
            int id = 0;
            for (ManorHarvestData harvestData : harvestModel.getHarvestDataMap().values()) {
                ManorConfig manorConfig = ManorMgr.getManorConfigMap().get(harvestData.getOutPutId());
                if (manorConfig != null && manorConfig.getType() == belong) {
                    id = manorConfig.getId();
                    break;
                }
            }
            changeSkin(id, skinId, eManorBigType.OutPut.getValue());
        } else {
            int id = 0;
            for (ManorBuildingData buildingData : buildingModel.getBuildingDataMap().values()) {
                ManorConfig manorConfig = ManorMgr.getManorConfigMap().get(buildingData.getId());
                if (manorConfig != null && manorConfig.getType() == belong) {
                    id = manorConfig.getId();
                    break;
                }
            }
            changeSkin(id, skinId, eManorBigType.Building.getValue());
        }
    }

    /**
     * 收获
     * @return
     */
    public int harvest() {
        return harvestModel.harvest();
    }

    /**
     * 找回收获
     */
    public ManorProto.ManorHarvestRespMsg.Builder recoveryHarvest(int recoveryDay, int discount) {
        return harvestModel.recoveryHarvest(recoveryDay, discount);
    }

    /**
     * 附加技能升级
     *
     * @param id
     * @return
     */
    public int specialSkillLevelUp(int id) {
        return harvestModel.specialSkillLevelUp(id);
    }

    public int specialSkillLevelUpTogether(int id) {
        return harvestModel.specialSkillLevelUpTogether(id);
    }

    /**
     * 庄园数据初始化
     */
    public void initUserManorData() {
        // 身份解锁
        if (!SystemOpenMgr.systemOpen(player, eSystemId.ManorSystem.getValue())) {
            return;
        }
        if (userManorData == null) {
            userManorData = new UserManorData();
            userManorData.setUserId(getUserId());
            userManorData.setProsperousValue(0L);
            userManorData.setFarmLandUnLock(0);
            userManorData.setInsertOption();
            harvestModel = new ManorHarvestModel(new ConcurrentHashMap<>(), player);
            guestModel = new ManorGuestModel(new ConcurrentHashMap<>(), player);
            buildingModel = new ManorBuildingModel(new ConcurrentHashMap<>(), player);
            technologyModel = new ManorTechnologyModel(new ConcurrentHashMap<>(), player);
            linleeSkinCheck(false);
        }
    }

    /**
     * 增加繁荣度
     * @param value
     */
    public void addProsperousValue(long value, String getWay) {
        userManorData.setProsperousValue(userManorData.getProsperousValue() + value);
        RankMgr.changeUserRank(eBigRankType.Normal.getValue(), player.getUserId(), BigInteger.valueOf(userManorData.getProsperousValue()), eRankType.ManorProsperousValue.getValue(), "");
        player.notifyListener(eGamePlayerEventType.ManorProsperousValue.getValue(), userManorData.getProsperousValue());
        player.notifyListener(eGamePlayerEventType.ManorProsperousValueAdd.getValue(), value);
        LogMgr.addLogManorProsperousValueGet(new LogManorProsperousValueGet(player.getUserId(), value, getWay, new Date()));
        notifyOpenFishPond();
    }

    /**
     * 通知解锁鱼塘
     */
    public void notifyOpenFishPond() {
        //庄园还没解锁
        if (userManorData == null) {
            return;
        }
        //系统解锁
        if (SystemOpenMgr.systemOpen(player, eSystemId.FishPond.getValue()) &&
                //繁荣度要求
                FishPondMgr.checkFishPondOpen(player) &&
                //因为会提前初始化数据 所以解锁的时候要判断鱼塘等级
                fishPondModel.getFishPondData().getFishPondLv() == 0) {
            fishPondModel.init();
        }
    }

    /**
     * 解锁地块区域
     * @return
     */
    public int unLockLand() {
        int unLockId = userManorData.getFarmLandUnLock() + 1;
        int minPosition = ((unLockId - 1) * 16);
        int maxPosition = unLockId * 16;
        int needTitleId = -1;
        Map<Integer, ManorConfig> manorConfigMap = ManorMgr.getManorConfigMap();
        for (ManorConfig manorConfig : manorConfigMap.values()) {
            if (manorConfig.getPosition() > minPosition && manorConfig.getPosition() <= maxPosition) {
                if (needTitleId == -1 || needTitleId > manorConfig.getUnlock()) {
                    needTitleId = manorConfig.getUnlock();
                }
            }
        }
        if (needTitleId == -1 || player.getTitleId() < needTitleId) {
            return GameErrorCode.E_MANOR_TITLE_ID_LIMIT;
        }
        userManorData.setFarmLandUnLock(unLockId);
        syncManorData();
        return 0;
    }

    public void notifySkinAdd(SkinInfo skinInfo) {
        harvestModel.notifySkinAdd(skinInfo);
    }

    public void notifyGuestAdd(int id) {
        harvestModel.notifyGuestAdd(id);
    }

    public void notifyBuildingAdd(int id) {
        harvestModel.notifyBuildingAdd(id);
    }

    @Override
    public boolean afterLoadData() {
        return false;
    }

    @Override
    public boolean saveData() {
        if (fishPondModel != null) {
            fishPondModel.save();
        }

        if (userManorData == null) {
            return true;
        }
        if (userManorData.isInsertOption()) {
            UserManorBusiness.add(userManorData);
        } else if (userManorData.isUpdateOption()) {
            UserManorBusiness.update(userManorData);
        }
        harvestModel.save();
        guestModel.save();
        buildingModel.save();
        technologyModel.save();

        List<ManorHelpRecord> tempList = new ArrayList<>(manorHelpRecordList);
        for(ManorHelpRecord record : tempList){
            if(record.isInsertOption()){
                UserManorBusiness.addManorHelpRecord(record);
            }else if(record.isUpdateOption()){
                UserManorBusiness.updateManorHelpRecord(record);
            }
        }
        return true;
    }

    /**
     * 更改庄园物件昵称
     * @param id
     * @param nickName
     * @return
     */
    public int changeNickName(int id, String nickName) {
        return harvestModel.changeNickName(id, nickName);
    }

    public void syncManorData() {
        if (userManorData != null) {
            player.sendPacket(ClientProtocol.U_MANOR_SYNC_DATA, ManorPb.getManorDataMsg(userManorData, harvestModel, guestModel, buildingModel, technologyModel, player));
        }
    }

    public ManorProto.ManorVisitOtherRespMsg.Builder getVisitRespMsg() {
        if (userManorData == null) {
            ManorProto.ManorVisitOtherRespMsg.Builder respMsg = ManorProto.ManorVisitOtherRespMsg.newBuilder();
            respMsg.setRet(GameErrorCode.E_MANOR_VISIT_PLAYER_MANOR_IS_LOCK);
            return respMsg;
        }
        return ManorPb.getManorVisitOtherRespMsg(userManorData, harvestModel.getHarvestDataMap(), guestModel.getGuestDataMap(), buildingModel.getBuildingDataMap(), player.getUserInfo());
    }


    public int unLockGuestSkin(int skinId) {
        if (guestModel != null) {
            return guestModel.unLockSkin(skinId);
        }
        return 0;
    }

    public void notifyGuestSkinAdd(int guestSkinId) {
        if (harvestModel != null) {
            harvestModel.notifyGuestSkinAdd(guestSkinId);
        }
    }

    public void npcTalkRefresh() {
        if (userManorData != null && ManorMgr.isNpcTalkRefreshTime(userManorData)) {
            ManorNpcTalkInfo npcTalkEvent = ManorMgr.getRandomNpcTalkEvent(guestModel.getGuestDataMap());
            if (npcTalkEvent == null) {
                return;
            }
            userManorData.setEventId(npcTalkEvent.getEventId());
            userManorData.setGetReward(false);
            userManorData.setReward(npcTalkEvent.getReward());
            userManorData.setRefreshTime(System.currentTimeMillis());
            syncManorData();
        }
    }

    //获取npc对话奖励
    public void getNpcTalkReward(ManorProto.GetManorTalkRewardRespMsg.Builder respMsg){
        if(userManorData.isGetReward()){
            respMsg.setRet(GameErrorCode.E_NPC_TALK_EVENT_IS_GETREWARD);
            return;
        }
        userManorData.setGetReward(true);
        Property totalReward = new Property();
        String[] split = GameConfig.MANOR_NPC_TALK_EVENT_OUT_PUT_REWARD_TIME_PARAM.split("\\|");
        List<Integer> weightList = new ArrayList<>();
        for (String str : split) {
            weightList.add(Integer.parseInt(str.split(";")[1]));
        }
        int index = RandomHelper.getRandomIndexByWeight(weightList);
        int min = Integer.parseInt(split[index].split(";")[0]);
        Property outPutReward = harvestModel.getUseGoodGet(min, 0, 1);
        totalReward.addProperty(outPutReward);
        totalReward.addProperty(PropertyHelper.parseStringToProperty(userManorData.getReward()));
        player.getModule(CurrencyModule.class).addCurrency(totalReward, eLogMoneyType.NpcEvent, eLogMoneyType.NpcTalkEventGetReward);
        syncManorData();
        respMsg.setReward(PropertyHelper.parsePropertyToString(totalReward));
        respMsg.setRet(0);
        long yieldCount = 0L;
        for (BigInteger value : outPutReward.getGoods().values()) {
            yieldCount += value.longValue();
        }
        ManorMgr.addRankActivityYieldCount(userManorData, yieldCount, player);
    }

    public String getBuildingArr() {
        String buildingArr = "";
        Map<Integer, ManorBuildingData> buildingDataMap = buildingModel.getBuildingDataMap();
        for (ManorBuildingData buildingData : buildingDataMap.values()) {
            buildingArr += buildingData.getId() + ";";
        }
        return buildingArr;
    }

    public String getGuestArr() {
        String guestArr = "";
        for (ManorGuestData guestData : guestModel.getGuestDataMap().values()) {
            guestArr += guestData.getId() + ";";
        }
        return guestArr;
    }

    @Override
    public void afterLogin() {
        try {
            //修复等级异常的鱼
            if (fishPondModel != null && fishPondModel.getFishDataMap() != null) {
                for (FishData fishData : fishPondModel.getFishDataMap().values()) {
                    if (fishData.getLv() < 30) {
                        continue;
                    }
                    int upgradeSkillId = FishPondMgr.getFishUpgradeSkillConfig(fishData.getFishId());
                    if (upgradeSkillId == 0) {
                        continue;
                    }
                    SkillInfo skillInfo = SkillMgr.getSkillInfo(upgradeSkillId);
                    if (skillInfo == null) {
                        continue;
                    }
                    if (fishData.getLv() > skillInfo.getMaxLevel()) {
                        log.error("修复玩家:{}的鱼:{},等级从{}=>{}", getUserId(), fishData.getFishId(), fishData.getLv(), skillInfo.getMaxLevel());
                        fishData.setLv(skillInfo.getMaxLevel());
                    }
                }
            }
        }catch (Exception e) {
            log.error(e);
        }


        ManorMgr.checkManorHelpRecover(player);
        syncManorData();
        removeActivityData();
        if (harvestModel != null) {
            harvestModel.removeActivityData();
        }
        notifyOpenFishPond();
        if (fishPondModel != null && fishPondModel.getFishPondData() != null) {
            fishPondModel.resetFishingState();
            fishPondModel.syncFishPondData();
            fishPondModel.checkAndReset();
            fishPondModel.syncPatronsBindMsg(fishPondModel.getPatronsFishBindingDataMap().values());
        }
    }

    public void removeActivityData() {
        //登陆后移除已过期的活动数据
        boolean isUpdate = false;
        if (userManorData == null) {
            return;
        }
        Map<Integer, Long> rankActivityDataMap = userManorData.getRankActivityDataMap();
        if (rankActivityDataMap == null) {
            return;
        }
        synchronized (rankActivityDataMap) {
            List<Integer> needRemoveList = new ArrayList<>();
            for (Map.Entry<Integer, Long> entry : rankActivityDataMap.entrySet()) {
                List<Integer> activityIdList = NormalActivityMgr.getOpenManorRankActivityIdList();
                if (!activityIdList.contains(entry.getKey())) {
                    needRemoveList.add(entry.getKey());
                    isUpdate = true;
                }
            }
            for (Integer activityId : needRemoveList) {
                rankActivityDataMap.remove(activityId);
            }
            if (isUpdate) {
                userManorData.setUpdateOption();
            }
        }
    }

    public void addManorHelpRecord(ManorHelpRecord manorHelpRecord) {
        synchronized (manorHelpRecordList) {
            if (manorHelpRecordList.size() >= GameConfig.MANOR_HEART_RECORD_MAX_COUNT) {
                manorHelpRecordList.removeLast();
            }
            manorHelpRecordList.addFirst(manorHelpRecord);
        }
        //通知被协助了
        player.sendPacket(ClientProtocol.U_MANOR_NOTICE_MANOR_HELP, ManorPb.parseNoticeManorHelpMsg(manorHelpRecord));
        syncManorData();
    }

    public void getManorHelpRecordList() {
        player.sendPacket(ClientProtocol.U_MANOR_GET_HELP_RECORD_LIST, ManorPb.parseManorHelpRecordListMsg(manorHelpRecordList));
    }

    public void resetOneDay() {
        try {
            notifyOpenFishPond();
            if (fishPondModel != null) {
                fishPondModel.resetOneDay();
            }
        } catch (Exception e) {
            logger.error("fish pond reset error", e);
        }
    }




    public void baginChanges() {
        
    }

    public Map<Integer, ManorTechnologyData> getTechnologyDataMap() {
        Map<Integer, ManorTechnologyData> technologyDataMap = new ConcurrentHashMap<>();
        if (technologyModel != null) {
            technologyDataMap = technologyModel.getTechnologyDataMap();
        }
        return technologyDataMap;
    }

    public Map<Integer, FishData> getFishDataMap() {
        Map<Integer, FishData> fishDataMap = new ConcurrentHashMap<>();
        if (fishPondModel != null) {
            fishDataMap = fishPondModel.getFishDataMap();
        }
        return fishDataMap;
    }

    public void addOpHelpUserId(long userId){
        synchronized (currHelpUserIdList) {
            if (!isOpHelpUser(userId)) {
                currHelpUserIdList.add(userId);
            }
        }
    }

    public void removeOpHelpUserId(long userId){
        synchronized (currHelpUserIdList) {
            if (isOpHelpUser(userId)) {
                currHelpUserIdList.remove(userId);
            }
        }
    }

    public boolean isOpHelpUser(long userId){
        return currHelpUserIdList.contains(userId);
    }

    /**
    * 描述：暴富鸭皮肤检测
    * 作者：zrq
    * 时间：2023/6/12
    * 参数：

    * 返回值：
    **/
    public void linleeSkinCheck(boolean isSync){
        int linkageSwitch;
        boolean useReview = false;
        int channelId = ServerListMgr.getChannelId(GameServer.getInstance().getServerId());
        if(eChannelType.isMainLandChannel(channelId)){
            ServerInfo serverInfo = ServerListMgr.getServerInfo(GameServer.getInstance().getServerId());
            if(null != serverInfo && serverInfo.getServerType() == ServerListMgr.SERVER_TYPE_REVIEW){//提审服用提审配置
                useReview = true;
            }
        }
        if(useReview){
            linkageSwitch = ChannelConfig.LIN_LEE_LINKAGE_SWITCH_REVIEW;
        }else {
            linkageSwitch = ChannelConfig.LIN_LEE_LINKAGE_SWITCH;
        }
        if (linkageSwitch == 1) {
            SkinModule skinModule = player.getModule(SkinModule.class);
            int skinId = ConfigMgr.getLinLeeSkinReplaceId();
            if (!skinModule.isSkinExist(skinId)) {
                if(null != harvestModel) {
                    skinModule.useSkin(skinId);
                }
                if (skinModule.isSkinExist(skinId)) {
                    if(null != harvestModel) {
                        harvestModel.changeLinLeeSkin(ConfigMgr.getLinLeeSkinReplaceType(), skinId);
                        if (isSync) {
                            syncManorData();
                        }
                    }
                }
            }
        } else {
            if(null != harvestModel) {
                boolean isChange = harvestModel.linLeeSkinCloseReset(ConfigMgr.getLinLeeSkinReplaceType(), ConfigMgr.getLinLeeSkinReplaceId());
                if (isChange && isSync) {
                    syncManorData();
                }
            }
        }
    }
}
